package com.java.architect.manager.aop;

import com.google.common.cache.Cache;

import com.java.architect.utils.CacheType;
import com.java.architect.utils.CacheUtils;
import com.java.architect.utils.SpelUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;

@Slf4j
@Aspect
@Component
@SuppressWarnings({"rawtypes","unchecked"})
public class DataCacheEvictAspect {

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Pointcut("@annotation(com.java.architect.manager.aop.DataCacheEvict)")
    public void pointCut() {

    }


    @Around(value = "pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        DataCacheEvict dataCache = method.getAnnotation(DataCacheEvict.class);

        boolean isLocal = false;
        boolean isRedis = false;

        for (CacheType cacheType : dataCache.type()) {
            if(cacheType == CacheType.LOCAL){
                isLocal = true;
            }
            if(cacheType == CacheType.REDIS){
                isRedis = true;
            }
        }

        Object returnObj = joinPoint.proceed();
        for (String key : dataCache.key()) {
            String cacheKey = SpelUtils.parseKey(key, joinPoint);
            String redisKey = CacheUtils.getRedisKey(dataCache.group(), cacheKey);

            if(isLocal){
                Cache cacheManager = CacheUtils.getCacheManager(dataCache.group());
                if(cacheManager != null){
                    cacheManager.invalidate(cacheKey);
                }
            }

            if(isRedis){
                this.stringRedisTemplate.delete(redisKey);
            }
        }
        return returnObj;
    }
}
